﻿using System;
using Moq;
using Soundteller.Audio.Model;
using Soundteller.Audio.Repositories.Interfaces;
using Soundteller.Audio.Services;
using Soundteller.Audio.Services.Interfaces;
using Soundteller.Common.Tests;
using Soundteller.Bus.Services.Interfaces;

namespace Soundteller.Audio.Tests.Unit.Services.MetronomeSpecifications
{
    public abstract class MetronomeTestBase : TestBase
    {
        protected IMetronome Metronome { get; private set; }

        protected Mock<IBeatCalculator> BeatCalculator { get; private set; }
        protected Mock<ISongRepository> SongRepository { get; private set; }
        protected Mock<IBeatRepository> BeatRepository { get; private set; }
        protected Mock<ISoundBufferRepository> SoundBufferRepository { get; private set; }
        protected Mock<IPublisher> Publisher { get; private set; }

        protected Song UpdatedSong { get; private set; }

        protected abstract TimeSpan ElapsedTime{ get; }

        protected override void Arrange()
        {
            BeatCalculator = new Mock<IBeatCalculator>();

            SongRepository = new Mock<ISongRepository>();
            SongRepository.Setup(r => r.GetActiveSong()).Returns(new Song());
            SongRepository.Setup(r => r.Update(It.IsAny<Song>())).Callback<Song>(s => UpdatedSong = s);

            BeatRepository = new Mock<IBeatRepository>();
            SoundBufferRepository = new Mock<ISoundBufferRepository>();
            Publisher = new Mock<IPublisher>();

            Metronome = new Metronome(BeatCalculator.Object, SongRepository.Object, BeatRepository.Object, SoundBufferRepository.Object, Publisher.Object);
        }

        protected override void Act()
        {
            Metronome.Tick(ElapsedTime);
        }
    }
}